package flex.persistence {
	import mx.utils.ArrayUtil;
	import mx.utils.StringUtil;
	
	public class CascadeType extends AbstractType {
		protected static var localInstantiation:Boolean = false;
		
		private static var _ALL:CascadeType; 
		public static function get ALL():CascadeType {
			if(!_ALL) { 
				localInstantiation = true; 
				_ALL = new CascadeType("ALL", 255);
				localInstantiation = false;
			}
			return _ALL; 
		} 
		private static var _NONE:CascadeType; 
		public static function get NONE():CascadeType {
			if(!_NONE) { 
				localInstantiation = true; 
				_NONE = new CascadeType("NONE", 0);
				localInstantiation = false;
			}
			return _NONE;
		} 

		private static var _MERGE:CascadeType; 
		public static function get MERGE():CascadeType {
			if(!_MERGE) { 
				localInstantiation = true; 
				_MERGE = new CascadeType("MERGE", 1);
				localInstantiation = false;
			}
			return _MERGE;
		} 
		private static var _PERSIST:CascadeType; 
		public static function get PERSIST():CascadeType {
			if(!_PERSIST) { 
				localInstantiation = true; 
				_PERSIST = new CascadeType("PERSIST", 2);
				localInstantiation = false;
			}
			return _PERSIST;
		} 
		private static var _REMOVE:CascadeType; 
		public static function get REMOVE():CascadeType {
			if(!_REMOVE) { 
				localInstantiation = true; 
				_REMOVE = new CascadeType("REMOVE", 4);
				localInstantiation = false;
			}
			return _REMOVE;
		} 

		public static function valueOf(name:String):CascadeType {
			var names:Array;
			var result:CascadeType = CascadeType.NONE;
			if(!name) return result;
			var temp:CascadeType;
			if(name.indexOf(",")!=-1) {
				names = name.split(",");
				localInstantiation = true; 
				result = new CascadeType(name, 0);
				localInstantiation = false;
				for each(var n:String in names) {
					temp = valueOf(n);
					result.val += temp.val;
				}
			} else {
				for each(var val:CascadeType in values()) {
					if(val.name.toUpperCase() == name.toUpperCase()) result = val;
				}
			}
			return result;
		}
		
		public static function values():Array {
			return [NONE, ALL, MERGE, PERSIST, REMOVE];
		}
		
		protected var val:uint;
		public function CascadeType(name:String, val:uint) {
			if(!localInstantiation) throw Error("Private constructor");
			this.name = name;
			this.val = val;
		}
		
		
		public function getValue():int {
			return this.val;
		}

		public function and(obj:Object):CascadeType {
			if(this.val == obj.val) return this;
			else {
				var val:int = this.val & obj.val;
				var names:String = "";
				for each(var c:CascadeType in values()) if(c.val & val) names +=","+c.name;
				names = names.substr(1);
				return valueOf(names);	
			}
		}
		
	}
}